package cn.itcast.mq.config;

import org.springframework.amqp.ImmediateRequeueAmqpException;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.ImmediateRequeueMessageRecoverer;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CommonConfig {

    /**
     * @description： 交换机持久化
     * @date：2024/3/23 20:39
     * @return：
     **/
    @Bean
    public DirectExchange directExchange() {
        //参数：交换机名称，是否持久化，未绑定队列时是否自动删除  交换机默认持久化
        return new DirectExchange("simple.direct", true, false);
    }

    /**
     * @description： 队列持久化
     * @date：2024/3/23 20:40
     * @return：
     **/
    @Bean
    public Queue simpleQueue() {
        //return new Queue("simple.queue");
        //队列SpringAMQP创建的队列默认持久化
        return QueueBuilder.durable("simple.queue").build();
    }

    /**
     * @description： 处理失败消息的交换机
     * @date：2024/3/24 16:03
     * @return：
     **/
    @Bean
    public DirectExchange errorMessageExchange() {
        return new DirectExchange("error.direct");
    }

    /**
     * @description： 处理失败消息的队列
     * @date：2024/3/24 16:03
     * @return：
     **/
    @Bean
    public Queue errorQueue() {
        return new Queue("error.queue", true);
    }

    /**
     * @description： 失败消息交换机和队列绑定
     * @date：2024/3/24 16:04
     * @return：
     **/
    @Bean
    public Binding errorBinding() {
        return BindingBuilder.bind(errorQueue()).to(errorMessageExchange()).with("error");
    }

    /**
     * @description： 重试耗尽后返回nack，将消息重新放回队列 ，死循环
     * @date：2024/3/24 16:26
     * @return：
     **/
    //@Bean
    //public ImmediateRequeueMessageRecoverer immediateRequeueMessageRecoverer(){
    //    return new ImmediateRequeueMessageRecoverer();
    //}

    /**
     * @description： 重试耗尽后，将消息投递到指定交换机
     * @date：2024/3/24 16:24
     * @return：
     **/
    @Bean
    public MessageRecoverer republishMessageRecoverer(RabbitTemplate rabbitTemplate) {
        return new RepublishMessageRecoverer(rabbitTemplate, "error.direct", "error");
    }

    /**
     * @description： 创建死信交换机
     * @date：2024/3/24 17:39
     * @return：
     **/
    @Bean
    public DirectExchange ttlExchange() {
        return new DirectExchange("ttl.direct");
    }

    /**
     * @description： 创建死信队列
     * @date：2024/3/24 17:39
     * @return：
     **/
    @Bean
    public Queue ttlQueue() {
        return QueueBuilder.durable("ttl.queue") // 指定队列名称，并持久化
                .ttl(10000)                      // 设置队列的超时时间，10秒
                .deadLetterExchange("dl.direct") // 指定死信交换机
                .deadLetterRoutingKey("dl")      // 指定死信RoutingKey
                .build();
    }

    /**
     * @description： 将死信交换机和队列绑定
     * @date：2024/3/24  17:40
     * @return：
     **/
    @Bean
    public Binding simpleBinding() {
        return BindingBuilder.bind(ttlQueue()).to(ttlExchange()).with("ttl");
    }

    /**
     * @description： 惰性队列
     * @date：2024/3/24  20:47
     * @return：
     **/
    @Bean
    public Queue lazyQueue(){
        return QueueBuilder.durable("lazy.queue")
                .lazy()
                .build();
    }


    /**
     * @description： 普通队列
     * @date：2024/3/24  20:52
     * @return：
     **/
    @Bean
    public Queue normalQueue(){
        return QueueBuilder.durable("normal.queue").build();
    }
}
